home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / srcuc.zip / X11TERM.C < prev    next >
C/C++ Source or Header  |  1992-03-13  |  32KB  |  995 lines

  1. /* -*-C-*-
  2.  
  3. $Header: /usr/local/scheme/src/microcode/RCS/x11term.c,v 1.20 1992/03/14 00:08:54 cph Exp $
  4.  
  5. Copyright (c) 1989-92 Massachusetts Institute of Technology
  6.  
  7. This material was developed by the Scheme project at the Massachusetts
  8. Institute of Technology, Department of Electrical Engineering and
  9. Computer Science.  Permission to copy this software, to redistribute
  10. it, and to use it for any purpose is granted, subject to the following
  11. restrictions and understandings.
  12.  
  13. 1. Any copy made of this software must include this copyright notice
  14. in full.
  15.  
  16. 2. Users of this software agree to make their best efforts (a) to
  17. return to the MIT Scheme project any improvements or extensions that
  18. they make, so that these may be included in future releases; and (b)
  19. to inform MIT of noteworthy uses of this software.
  20.  
  21. 3. All materials developed as a consequence of the use of this
  22. software shall duly acknowledge such use, in accordance with the usual
  23. standards of acknowledging credit in academic research.
  24.  
  25. 4. MIT has made no warrantee or representation that the operation of
  26. this software will be error-free, and MIT is under no obligation to
  27. provide any services, by way of maintenance, update, or otherwise.
  28.  
  29. 5. In conjunction with products arising from the use of this material,
  30. there shall be no use of the name of the Massachusetts Institute of
  31. Technology nor of any adaptation thereof in any advertising,
  32. promotional, or sales literature without prior written consent from
  33. MIT in each case. */
  34.  
  35. /* X11 terminal for Edwin. */
  36.  
  37. #include "scheme.h"
  38. #include "prims.h"
  39. #include "x11.h"
  40.  
  41. struct xterm_extra
  42. {
  43.   /* Dimensions of the window, in characters.  Valid character
  44.      coordinates are nonnegative integers strictly less than these
  45.      limits. */
  46.   unsigned int x_size;
  47.   unsigned int y_size;
  48.  
  49.   /* Position of the cursor, in character coordinates. */
  50.   unsigned int cursor_x;
  51.   unsigned int cursor_y;
  52.  
  53.   /* Character map of the window's contents.  See `XTERM_CHAR_LOC' for
  54.      the address arithmetic. */
  55.   char * character_map;
  56.  
  57.   /* Bit map of the window's highlighting. */
  58.   char * highlight_map;
  59.  
  60.   /* Nonzero iff the cursor is drawn on the window. */
  61.   char cursor_visible_p;
  62.  
  63.   /* Nonzero iff the cursor should be drawn on the window. */
  64.   char cursor_enabled_p;
  65. };
  66.  
  67. #define XW_EXTRA(xw) ((struct xterm_extra *) ((xw) -> extra))
  68.  
  69. #define XW_X_CSIZE(xw) ((XW_EXTRA (xw)) -> x_size)
  70. #define XW_Y_CSIZE(xw) ((XW_EXTRA (xw)) -> y_size)
  71. #define XW_CURSOR_X(xw) ((XW_EXTRA (xw)) -> cursor_x)
  72. #define XW_CURSOR_Y(xw) ((XW_EXTRA (xw)) -> cursor_y)
  73. #define XW_CHARACTER_MAP(xw) ((XW_EXTRA (xw)) -> character_map)
  74. #define XW_HIGHLIGHT_MAP(xw) ((XW_EXTRA (xw)) -> highlight_map)
  75. #define XW_CURSOR_VISIBLE_P(xw) ((XW_EXTRA (xw)) -> cursor_visible_p)
  76. #define XW_CURSOR_ENABLED_P(xw) ((XW_EXTRA (xw)) -> cursor_enabled_p)
  77.  
  78. #define XTERM_CHAR_INDEX(xw, x, y) (((y) * (XW_X_CSIZE (xw))) + (x))
  79. #define XTERM_CHAR_LOC(xw, index) ((XW_CHARACTER_MAP (xw)) + (index))
  80. #define XTERM_CHAR(xw, index) (* (XTERM_CHAR_LOC (xw, index)))
  81. #define XTERM_HL_LOC(xw, index) ((XW_HIGHLIGHT_MAP (xw)) + (index))
  82. #define XTERM_HL(xw, index) (* (XTERM_HL_LOC (xw, index)))
  83.  
  84. #define XTERM_HL_GC(xw, hl) (hl ? (XW_REVERSE_GC (xw)) : (XW_NORMAL_GC (xw)))
  85.  
  86. #define HL_ARG(arg) arg_index_integer (arg, 2)
  87.  
  88. #define RESOURCE_NAME "schemeTerminal"
  89. #define RESOURCE_CLASS "SchemeTerminal"
  90. #define DEFAULT_GEOMETRY "80x40+0+0"
  91. #define BLANK_CHAR ' '
  92. #define DEFAULT_HL 0
  93.  
  94. #define XTERM_X_PIXEL(xw, x)                        \
  95.   (((x) * (FONT_WIDTH (XW_FONT (xw)))) + (XW_INTERNAL_BORDER_WIDTH (xw)))
  96.  
  97. #define XTERM_Y_PIXEL(xw, y)                        \
  98.   (((y) * (FONT_HEIGHT (XW_FONT (xw)))) + (XW_INTERNAL_BORDER_WIDTH (xw)))
  99.  
  100. #define XTERM_DRAW_CHARS(xw, x, y, s, n, gc)                \
  101.   XDrawImageString                            \
  102.     ((XW_DISPLAY (xw)),                            \
  103.      (XW_WINDOW (xw)),                            \
  104.      gc,                                \
  105.      (XTERM_X_PIXEL (xw, x)),                        \
  106.      ((XTERM_Y_PIXEL (xw, y)) + (FONT_BASE (XW_FONT (xw)))),        \
  107.      s,                                    \
  108.      n)
  109.  
  110. #define CURSOR_IN_RECTANGLE(xw, x_start, x_end, y_start, y_end)        \
  111.   (((x_start) <= (XW_CURSOR_X (xw)))                    \
  112.    && ((XW_CURSOR_X (xw)) < (x_end))                    \
  113.    && ((y_start) <= (XW_CURSOR_Y (xw)))                    \
  114.    && ((XW_CURSOR_Y (xw)) < (y_end)))
  115.  
  116. static void
  117. DEFUN (xterm_erase_cursor, (xw), struct xwindow * xw)
  118. {
  119.   if (XW_CURSOR_VISIBLE_P (xw))
  120.     {
  121.       unsigned int x = (XW_CURSOR_X (xw));
  122.       unsigned int y = (XW_CURSOR_Y (xw));
  123.       unsigned int index = (XTERM_CHAR_INDEX (xw, x, y));
  124.       XTERM_DRAW_CHARS
  125.     (xw, x, y,
  126.      (XTERM_CHAR_LOC (xw, index)),
  127.      1,
  128.      (XTERM_HL_GC (xw, (XTERM_HL (xw, index)))));
  129.       (XW_CURSOR_VISIBLE_P (xw)) = 0;
  130.     }
  131. }
  132.  
  133. static void
  134. DEFUN (xterm_draw_cursor, (xw), struct xwindow * xw)
  135. {
  136.   if ((XW_CURSOR_ENABLED_P (xw)) && (! (XW_CURSOR_VISIBLE_P (xw))))
  137.     {
  138.       unsigned int x = (XW_CURSOR_X (xw));
  139.       unsigned int y = (XW_CURSOR_Y (xw));
  140.       XTERM_DRAW_CHARS (xw, x, y,
  141.             (XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x, y)))),
  142.             1,
  143.             (XW_CURSOR_GC (xw)));
  144.       (XW_CURSOR_VISIBLE_P (xw)) = 1;
  145.     }
  146. }
  147.  
  148. static void
  149. DEFUN (xterm_process_event, (xw, event),
  150.        struct xwindow * xw AND
  151.        XEvent * event)
  152. {
  153. }
  154.  
  155. static XSizeHints *
  156. DEFUN (xterm_make_size_hints, (font, extra),
  157.        XFontStruct * font AND
  158.        unsigned int extra)
  159. {
  160.   XSizeHints * size_hints = (XAllocSizeHints ());
  161.   if (size_hints == 0)
  162.     error_external_return ();
  163.   (size_hints -> flags) = (PResizeInc | PMinSize | PBaseSize);
  164.   (size_hints -> width_inc) = (FONT_WIDTH (font));
  165.   (size_hints -> height_inc) = (FONT_HEIGHT (font));
  166.   (size_hints -> min_width) = extra;
  167.   (size_hints -> min_height) = extra;
  168.   (size_hints -> base_width) = extra;
  169.   (size_hints -> base_height) = extra;
  170.   return (size_hints);
  171. }
  172.  
  173. static void
  174. DEFUN (xterm_set_wm_normal_hints, (xw, size_hints, geometry_mask, x, y),
  175.        struct xwindow * xw AND
  176.        XSizeHints * size_hints AND
  177.        int geometry_mask AND
  178.        unsigned int x AND
  179.        unsigned int y)
  180. {
  181.   (size_hints -> flags) |=
  182.     ((((geometry_mask & XValue) && (geometry_mask & YValue))
  183.       ? USPosition : PPosition)
  184.      | (((geometry_mask & WidthValue) && (geometry_mask & HeightValue))
  185.     ? USSize : PSize));
  186.   (size_hints -> x) = x;
  187.   (size_hints -> y) = y;
  188.   (size_hints -> width) =
  189.     (((XW_X_CSIZE (xw)) * (size_hints -> width_inc))
  190.      + (size_hints -> base_width));
  191.   (size_hints -> height) =
  192.     (((XW_Y_CSIZE (xw)) * (size_hints -> height_inc))
  193.      + (size_hints -> base_height));
  194.   XSetWMNormalHints ((XW_DISPLAY (xw)), (XW_WINDOW (xw)), size_hints);
  195.   XFree ((caddr_t) size_hints);
  196. }
  197.  
  198. static void
  199. DEFUN (xterm_update_normal_hints, (xw), struct xwindow * xw)
  200. {
  201.   xterm_set_wm_normal_hints
  202.     (xw,
  203.      (xterm_make_size_hints
  204.       ((XW_FONT (xw)),
  205.        (2 * (XW_INTERNAL_BORDER_WIDTH (xw))))),
  206.      0, 0, 0);
  207. }
  208.  
  209. static void
  210. DEFUN (xterm_deallocate, (xw), struct xwindow * xw)
  211. {
  212.   free (XW_CHARACTER_MAP (xw));
  213.   free (XW_HIGHLIGHT_MAP (xw));
  214. }
  215.  
  216. static SCHEME_OBJECT
  217. DEFUN (xterm_x_coordinate_map, (xw, x), struct xwindow * xw AND unsigned int x)
  218. {
  219.   return (long_to_integer (x / (FONT_WIDTH (XW_FONT (xw)))));
  220. }
  221.  
  222. static SCHEME_OBJECT
  223. DEFUN (xterm_y_coordinate_map, (xw, y), struct xwindow * xw AND unsigned int y)
  224. {
  225.   return (long_to_integer (y / (FONT_HEIGHT (XW_FONT (xw)))));
  226. }
  227.  
  228. static void
  229. DEFUN (xterm_copy_map_line, (xw, x_start, x_end, y_from, y_to),
  230.        struct xwindow * xw AND
  231.        unsigned int x_start AND
  232.        unsigned int x_end AND
  233.        unsigned int y_from AND
  234.        unsigned int y_to)
  235. {
  236.   {
  237.     char * from_scan =
  238.       (XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y_from))));
  239.     char * from_end =
  240.       (XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x_end, y_from))));
  241.     char * to_scan =
  242.       (XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y_to))));
  243.     while (from_scan < from_end)
  244.       (*to_scan++) = (*from_scan++);
  245.   }
  246.   {
  247.     char * from_scan =
  248.       (XTERM_HL_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y_from))));
  249.     char * from_end =
  250.       (XTERM_HL_LOC (xw, (XTERM_CHAR_INDEX (xw, x_end, y_from))));
  251.     char * to_scan =
  252.       (XTERM_HL_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y_to))));
  253.     while (from_scan < from_end)
  254.       (*to_scan++) = (*from_scan++);
  255.   }
  256. }
  257.  
  258. static void
  259. DEFUN (xterm_dump_contents, (xw, x_start, x_end, y_start, y_end),
  260.        struct xwindow * xw AND
  261.        unsigned int x_start AND
  262.        unsigned int x_end AND
  263.        unsigned int y_start AND
  264.        unsigned int y_end)
  265. {
  266.   char * character_map = (XW_CHARACTER_MAP (xw));
  267.   char * highlight_map = (XW_HIGHLIGHT_MAP (xw));
  268.   if (x_start < x_end)
  269.     {
  270.       unsigned int yi;
  271.       for (yi = y_start; (yi < y_end); yi += 1)
  272.     {
  273.       unsigned int index = (XTERM_CHAR_INDEX (xw, 0, yi));
  274.       char * line_char = (&character_map[index]);
  275.       char * line_hl = (&highlight_map[index]);
  276.       unsigned int xi = x_start;
  277.       while (1)
  278.         {
  279.           unsigned int hl = (line_hl[xi]);
  280.           unsigned int xj = (xi + 1);
  281.           while ((xj < x_end) && ((line_hl[xj]) == hl))
  282.         xj += 1;
  283.           XTERM_DRAW_CHARS (xw, xi, yi,
  284.                 (&line_char[xi]),
  285.                 (xj - xi),
  286.                 (XTERM_HL_GC (xw, hl)));
  287.           if (xj == x_end)
  288.         break;
  289.           xi = xj;
  290.         }
  291.     }
  292.       if (CURSOR_IN_RECTANGLE (xw, x_start, x_end, y_start, y_end))
  293.     {
  294.       (XW_CURSOR_VISIBLE_P (xw)) = 0;
  295.       xterm_draw_cursor (xw);
  296.     }
  297.     }
  298. }
  299.  
  300. static void
  301. DEFUN (xterm_dump_rectangle, (xw, x, y, width, height),
  302.        struct xwindow * xw AND
  303.        unsigned int x AND
  304.        unsigned int y AND
  305.        unsigned int width AND
  306.        unsigned int height)
  307. {
  308.   XFontStruct * font = (XW_FONT (xw));
  309.   unsigned int fwidth = (FONT_WIDTH (font));
  310.   unsigned int fheight = (FONT_HEIGHT (font));
  311.   unsigned int border = (XW_INTERNAL_BORDER_WIDTH (xw));
  312.   if (x < border)
  313.     {
  314.       width -= (border - x);
  315.       x = 0;
  316.     }
  317.   else
  318.     x -= border;
  319.   if ((x + width) > (XW_X_SIZE (xw)))
  320.     width = ((XW_X_SIZE (xw)) - x);
  321.   if (y < border)
  322.     {
  323.       height -= (border - y);
  324.       y = 0;
  325.     }
  326.   else
  327.     y -= border;
  328.   if ((y + height) > (XW_Y_SIZE (xw)))
  329.     height = ((XW_Y_SIZE (xw)) - y);
  330.   xterm_dump_contents (xw,
  331.                (x / fwidth),
  332.                (((x + width) + (fwidth - 1)) / fwidth),
  333.                (y / fheight),
  334.                (((y + height) + (fheight - 1)) / fheight));
  335.   XFlush (XW_DISPLAY (xw));
  336. }
  337.  
  338. #define MIN(x, y) (((x) < (y)) ? (x) : (y))
  339.  
  340. static void
  341. DEFUN (xterm_reconfigure, (xw, width, height),
  342.        struct xwindow * xw AND
  343.        unsigned int width AND
  344.        unsigned int height)
  345. {
  346.   unsigned int extra = (2 * (XW_INTERNAL_BORDER_WIDTH (xw)));
  347.   unsigned int x_size = ((width < extra) ? 0 : (width - extra));
  348.   unsigned int y_size = ((height < extra) ? 0 : (height - extra));
  349.   if ((x_size != (XW_X_SIZE (xw))) || (y_size != (XW_Y_SIZE (xw))))
  350.     {
  351.       unsigned int x_csize = (x_size / (FONT_WIDTH (XW_FONT (xw))));
  352.       unsigned int y_csize = (y_size / (FONT_HEIGHT (XW_FONT (xw))));
  353.       char * new_char_map = (x_malloc (x_csize * y_csize));
  354.       char * new_hl_map = (x_malloc (x_csize * y_csize));
  355.       unsigned int old_x_csize = (XW_X_CSIZE (xw));
  356.       unsigned int min_x_csize = (MIN (x_csize, old_x_csize));
  357.       unsigned int min_y_csize = (MIN (y_csize, (XW_Y_CSIZE (xw))));
  358.       int x_clipped = (old_x_csize - x_csize);
  359.       char * new_scan_char = new_char_map;
  360.       char * new_scan_hl = new_hl_map;
  361.       char * new_end;
  362.       char * old_scan_char = (XW_CHARACTER_MAP (xw));
  363.       char * old_scan_hl = (XW_HIGHLIGHT_MAP (xw));
  364.       char * old_end;
  365.       unsigned int new_y = 0;
  366.       for (; (new_y < min_y_csize); new_y += 1)
  367.     {
  368.       old_end = (old_scan_char + min_x_csize);
  369.       while (old_scan_char < old_end)
  370.         {
  371.           (*new_scan_char++) = (*old_scan_char++);
  372.           (*new_scan_hl++) = (*old_scan_hl++);
  373.         }
  374.       if (x_clipped < 0)
  375.         {
  376.           new_end = (new_scan_char + ((unsigned int) (- x_clipped)));
  377.           while (new_scan_char < new_end)
  378.         {
  379.           (*new_scan_char++) = BLANK_CHAR;
  380.           (*new_scan_hl++) = DEFAULT_HL;
  381.         }
  382.         }
  383.       else if (x_clipped > 0)
  384.         {
  385.           old_scan_char += ((unsigned int) x_clipped);
  386.           old_scan_hl += ((unsigned int) x_clipped);
  387.         }
  388.     }
  389.       for (; (new_y < y_csize); new_y += 1)
  390.     {
  391.       new_end = (new_scan_char + x_csize);
  392.       while (new_scan_char < new_end)
  393.         {
  394.           (*new_scan_char++) = BLANK_CHAR;
  395.           (*new_scan_hl++) = DEFAULT_HL;
  396.         }
  397.     }
  398.       free (XW_CHARACTER_MAP (xw));
  399.       free (XW_HIGHLIGHT_MAP (xw));
  400.       (XW_X_SIZE (xw)) = x_size;
  401.       (XW_Y_SIZE (xw)) = y_size;
  402.       (XW_CLIP_X (xw)) = 0;
  403.       (XW_CLIP_Y (xw)) = 0;
  404.       (XW_CLIP_WIDTH (xw)) = x_size;
  405.       (XW_CLIP_HEIGHT (xw)) = y_size;
  406.       (XW_X_CSIZE (xw)) = x_csize;
  407.       (XW_Y_CSIZE (xw)) = y_csize;
  408.       (XW_CHARACTER_MAP (xw))= new_char_map;
  409.       (XW_HIGHLIGHT_MAP (xw))= new_hl_map;
  410.       xterm_dump_contents (xw, 0, 0, x_csize, y_csize);
  411.       xterm_update_normal_hints (xw);
  412.       XFlush (XW_DISPLAY (xw));
  413.     }
  414. }
  415.  
  416. DEFINE_PRIMITIVE ("XTERM-RECONFIGURE", Prim_xterm_reconfigure, 3, 3, 0)
  417. {
  418.   PRIMITIVE_HEADER (3);
  419.   xterm_reconfigure ((x_window_arg (1)),
  420.              (arg_nonnegative_integer (2)),
  421.              (arg_nonnegative_integer (3)));
  422.   PRIMITIVE_RETURN (UNSPECIFIC);
  423. }
  424.  
  425. DEFINE_PRIMITIVE ("XTERM-DUMP-RECTANGLE", Prim_xterm_dump_rectangle, 5, 5, 0)
  426. {
  427.   PRIMITIVE_HEADER (5);
  428.   xterm_dump_rectangle ((x_window_arg (1)),
  429.             (arg_nonnegative_integer (2)),
  430.             (arg_nonnegative_integer (3)),
  431.             (arg_nonnegative_integer (4)),
  432.             (arg_nonnegative_integer (5)));
  433.   PRIMITIVE_RETURN (UNSPECIFIC);
  434. }
  435.  
  436. DEFINE_PRIMITIVE ("XTERM-MAP-X-COORDINATE", Prim_xterm_map_x_coordinate, 2, 2, 0)
  437. {
  438.   PRIMITIVE_HEADER (2);
  439.   {
  440.     struct xwindow * xw = (x_window_arg (1));
  441.     unsigned int xp = (arg_nonnegative_integer (2));
  442.     int bx = (xp - (XW_INTERNAL_BORDER_WIDTH (xw)));
  443.     PRIMITIVE_RETURN
  444.       (long_to_integer
  445.        (((bx < 0) ? 0
  446.      : (bx >= (XW_X_SIZE (xw))) ? ((XW_X_SIZE (xw)) - 1)
  447.      : bx)
  448.     / (FONT_WIDTH (XW_FONT (xw)))));
  449.   }
  450. }
  451.  
  452. DEFINE_PRIMITIVE ("XTERM-MAP-Y-COORDINATE", Prim_xterm_map_y_coordinate, 2, 2, 0)
  453. {
  454.   PRIMITIVE_HEADER (2);
  455.   {
  456.     struct xwindow * xw = (x_window_arg (1));
  457.     unsigned int yp = (arg_nonnegative_integer (2));
  458.     int by = (yp - (XW_INTERNAL_BORDER_WIDTH (xw)));
  459.     PRIMITIVE_RETURN
  460.       (long_to_integer
  461.        (((by < 0) ? 0
  462.      : (by >= (XW_Y_SIZE (xw))) ? ((XW_Y_SIZE (xw)) - 1)
  463.      : by)
  464.     / (FONT_HEIGHT (XW_FONT (xw)))));
  465.   }
  466. }
  467.  
  468. DEFINE_PRIMITIVE ("XTERM-MAP-X-SIZE", Prim_xterm_map_x_size, 2, 2, 0)
  469. {
  470.   PRIMITIVE_HEADER (2);
  471.   {
  472.     struct xwindow * xw = (x_window_arg (1));
  473.     int width =
  474.       ((arg_nonnegative_integer (2)) - (2 * (XW_INTERNAL_BORDER_WIDTH (xw))));
  475.     PRIMITIVE_RETURN
  476.       (long_to_integer
  477.        ((width < 0) ? 0 : (width / (FONT_WIDTH (XW_FONT (xw))))));
  478.   }
  479. }
  480.  
  481. DEFINE_PRIMITIVE ("XTERM-MAP-Y-SIZE", Prim_xterm_map_y_size, 2, 2, 0)
  482. {
  483.   PRIMITIVE_HEADER (2);
  484.   {
  485.     struct xwindow * xw = (x_window_arg (1));
  486.     int height =
  487.       ((arg_nonnegative_integer (2)) - (2 * (XW_INTERNAL_BORDER_WIDTH (xw))));
  488.     PRIMITIVE_RETURN
  489.       (long_to_integer
  490.        ((height < 0) ? 0 : (height / (FONT_HEIGHT (XW_FONT (xw))))));
  491.   }
  492. }
  493.  
  494. DEFINE_PRIMITIVE ("XTERM-OPEN-WINDOW", Prim_xterm_open_window, 3, 3, 0)
  495. {
  496.   PRIMITIVE_HEADER (3);
  497.   {
  498.     struct xdisplay * xd = (x_display_arg (1));
  499.     Display * display = (XD_DISPLAY (xd));
  500.     struct drawing_attributes attributes;
  501.     struct xwindow_methods methods;
  502.     CONST char * resource_name = RESOURCE_NAME;
  503.     CONST char * resource_class = RESOURCE_CLASS;
  504.     int map_p;
  505.     
  506.     x_decode_window_map_arg
  507.       ((ARG_REF (3)), (&resource_name), (&resource_class), (&map_p));
  508.     x_default_attributes
  509.       (display, resource_name, resource_class, (&attributes));
  510.     (methods . deallocator) = xterm_deallocate;
  511.     (methods . event_processor) = xterm_process_event;
  512.     (methods . x_coordinate_map) = xterm_x_coordinate_map;
  513.     (methods . y_coordinate_map) = xterm_y_coordinate_map;
  514.     (methods . update_normal_hints) = xterm_update_normal_hints;
  515.     {
  516.       unsigned int extra = (2 * (attributes . internal_border_width));
  517.       int x_pos;
  518.       int y_pos;
  519.       int x_size;
  520.       int y_size;
  521.       XSizeHints * size_hints =
  522.     (xterm_make_size_hints ((attributes . font), extra));
  523.       int geometry_mask =
  524.     (XWMGeometry
  525.      (display,
  526.       (DefaultScreen (display)),
  527.       (((ARG_REF (2)) == SHARP_F)
  528.        ? (x_get_default
  529.           (display, resource_name, resource_class,
  530.            "geometry", "Geometry", 0))
  531.        : (STRING_ARG (2))),
  532.       DEFAULT_GEOMETRY,
  533.       (attributes . border_width),
  534.       size_hints,
  535.       (&x_pos), (&y_pos), (&x_size), (&y_size),
  536.       (& (size_hints -> win_gravity))));
  537.       unsigned int x_csize =
  538.     ((x_size - (size_hints -> base_width)) / (size_hints -> width_inc));
  539.       unsigned int y_csize =
  540.     ((y_size - (size_hints -> base_height)) / (size_hints -> height_inc));
  541.       Window window =
  542.     (XCreateSimpleWindow
  543.      (display, (RootWindow (display, (DefaultScreen (display)))),
  544.       x_pos, y_pos, x_size, y_size,
  545.       (attributes . border_width),
  546.       (attributes . border_pixel),
  547.       (attributes . background_pixel)));
  548.       if (window == 0)
  549.     error_external_return ();
  550.       {
  551.     struct xwindow * xw =
  552.       (x_make_window
  553.        (xd,
  554.         window,
  555.         (x_size - (size_hints -> base_width)),
  556.         (y_size - (size_hints -> base_height)),
  557.         (&attributes),
  558.         (&methods),
  559.         (sizeof (struct xterm_extra))));
  560.     unsigned int map_size = (x_csize * y_csize);
  561.     (XW_X_CSIZE (xw)) = x_csize;
  562.     (XW_Y_CSIZE (xw)) = y_csize;
  563.     (XW_CURSOR_X (xw)) = 0;
  564.     (XW_CURSOR_Y (xw)) = 0;
  565.     (XW_CURSOR_VISIBLE_P (xw)) = 0;
  566.     (XW_CURSOR_ENABLED_P (xw)) = 1;
  567.     {
  568.       char * scan = (x_malloc (map_size));
  569.       char * end = (scan + map_size);
  570.       (XW_CHARACTER_MAP (xw)) = scan;
  571.       while (scan < end)
  572.         (*scan++) = BLANK_CHAR;
  573.     }
  574.     {
  575.       char * scan = (x_malloc (map_size));
  576.       char * end = (scan + map_size);
  577.       (XW_HIGHLIGHT_MAP (xw)) = scan;
  578.       while (scan < end)
  579.         (*scan++) = DEFAULT_HL;
  580.     }
  581.     (size_hints -> flags) |= PWinGravity;
  582.     xterm_set_wm_normal_hints
  583.       (xw, size_hints, geometry_mask, x_pos, y_pos);
  584.     xw_set_wm_input_hint (xw, 1);
  585.     xw_set_wm_name (xw, "scheme-terminal");
  586.     xw_set_wm_icon_name (xw, "scheme-terminal");
  587.     xw_make_window_map (xw, resource_name, resource_class, map_p);
  588.     PRIMITIVE_RETURN (XW_TO_OBJECT (xw));
  589.       }
  590.     }
  591.   }
  592. }
  593.  
  594. DEFINE_PRIMITIVE ("XTERM-X-SIZE", Prim_xterm_x_size, 1, 1, 0)
  595. {
  596.   PRIMITIVE_HEADER (1);
  597.   PRIMITIVE_RETURN (long_to_integer (XW_X_CSIZE (x_window_arg (1))));
  598. }
  599.  
  600. DEFINE_PRIMITIVE ("XTERM-Y-SIZE", Prim_xterm_y_size, 1, 1, 0)
  601. {
  602.   PRIMITIVE_HEADER (1);
  603.   PRIMITIVE_RETURN (long_to_integer (XW_Y_CSIZE (x_window_arg (1))));
  604. }
  605.  
  606. DEFINE_PRIMITIVE ("XTERM-SET-SIZE", Prim_xterm_set_size, 3, 3, 0)
  607. {
  608.   struct xwindow * xw;
  609.   int extra;
  610.   XFontStruct * font;
  611.   PRIMITIVE_HEADER (3);
  612.   xw = (x_window_arg (1));
  613.   extra = (2 * (XW_INTERNAL_BORDER_WIDTH (xw)));
  614.   font = (XW_FONT (xw));
  615.   XResizeWindow
  616.     ((XW_DISPLAY (xw)),
  617.      (XW_WINDOW (xw)),
  618.      (((arg_nonnegative_integer (2)) * (FONT_WIDTH (font))) + extra),
  619.      (((arg_nonnegative_integer (3)) * (FONT_HEIGHT (font))) + extra));
  620.   PRIMITIVE_RETURN (UNSPECIFIC);
  621. }
  622.  
  623. DEFINE_PRIMITIVE ("XTERM-ENABLE-CURSOR", Prim_xterm_enable_cursor, 2, 2, 0)
  624. {
  625.   PRIMITIVE_HEADER (2);
  626.   (XW_CURSOR_ENABLED_P (x_window_arg (1))) = (BOOLEAN_ARG (2));
  627.   PRIMITIVE_RETURN (UNSPECIFIC);
  628. }
  629.  
  630. DEFINE_PRIMITIVE ("XTERM-ERASE-CURSOR", Prim_xterm_erase_cursor, 1, 1, 0)
  631. {
  632.   PRIMITIVE_HEADER (1);
  633.   xterm_erase_cursor (x_window_arg (1));
  634.   PRIMITIVE_RETURN (UNSPECIFIC);
  635. }
  636.  
  637. DEFINE_PRIMITIVE ("XTERM-DRAW-CURSOR", Prim_xterm_draw_cursor, 1, 1, 0)
  638. {
  639.   PRIMITIVE_HEADER (1);
  640.   xterm_draw_cursor (x_window_arg (1));
  641.   PRIMITIVE_RETURN (UNSPECIFIC);
  642. }
  643.  
  644. DEFINE_PRIMITIVE ("XTERM-WRITE-CURSOR!", Prim_xterm_write_cursor, 3, 3, 0)
  645. {
  646.   PRIMITIVE_HEADER (3);
  647.   {
  648.     struct xwindow * xw = (x_window_arg (1));
  649.     unsigned int x = (arg_index_integer (2, (XW_X_CSIZE (xw))));
  650.     unsigned int y = (arg_index_integer (3, (XW_Y_CSIZE (xw))));
  651.     if ((x != (XW_CURSOR_X (xw))) || (y != (XW_CURSOR_Y (xw))))
  652.       {
  653.     xterm_erase_cursor (xw);
  654.     (XW_CURSOR_X (xw)) = x;
  655.     (XW_CURSOR_Y (xw)) = y;
  656.       }
  657.     xterm_draw_cursor (xw);
  658.   }
  659.   PRIMITIVE_RETURN (UNSPECIFIC);
  660. }
  661.  
  662. DEFINE_PRIMITIVE ("XTERM-WRITE-CHAR!", Prim_xterm_write_char, 5, 5, 0)
  663. {
  664.   PRIMITIVE_HEADER (5);
  665.   {
  666.     struct xwindow * xw = (x_window_arg (1));
  667.     unsigned int x = (arg_index_integer (2, (XW_X_CSIZE (xw))));
  668.     unsigned int y = (arg_index_integer (3, (XW_Y_CSIZE (xw))));
  669.     int c = (arg_ascii_char (4));
  670.     unsigned int hl = (HL_ARG (5));
  671.     unsigned int index = (XTERM_CHAR_INDEX (xw, x, y));
  672.     char * map_ptr = (XTERM_CHAR_LOC (xw, index));
  673.     (*map_ptr) = c;
  674.     (XTERM_HL (xw, index)) = hl;
  675.     XTERM_DRAW_CHARS (xw, x, y, map_ptr, 1, (XTERM_HL_GC (xw, (xw, hl))));
  676.     if (((XW_CURSOR_X (xw)) == x) && ((XW_CURSOR_Y (xw)) == y))
  677.       {
  678.     (XW_CURSOR_VISIBLE_P (xw)) = 0;
  679.     xterm_draw_cursor (xw);
  680.       }
  681.   }
  682.   PRIMITIVE_RETURN (UNSPECIFIC);
  683. }
  684.  
  685. DEFINE_PRIMITIVE ("XTERM-WRITE-SUBSTRING!", Prim_xterm_write_substring, 7, 7, 0)
  686. {
  687.   PRIMITIVE_HEADER (7);
  688.   CHECK_ARG (4, STRING_P);
  689.   {
  690.     struct xwindow * xw = (x_window_arg (1));
  691.     unsigned int x = (arg_index_integer (2, (XW_X_CSIZE (xw))));
  692.     unsigned int y = (arg_index_integer (3, (XW_Y_CSIZE (xw))));
  693.     SCHEME_OBJECT string = (ARG_REF (4));
  694.     unsigned int end = (arg_index_integer (6, ((STRING_LENGTH (string)) + 1)));
  695.     unsigned int start = (arg_index_integer (5, (end + 1)));
  696.     unsigned int hl = (HL_ARG (7));
  697.     unsigned int length = (end - start);
  698.     unsigned int index = (XTERM_CHAR_INDEX (xw, x, y));
  699.     if ((x + length) > (XW_X_CSIZE (xw)))
  700.       error_bad_range_arg (2);
  701.     {
  702.       unsigned char * string_scan = (STRING_LOC (string, start));
  703.       unsigned char * string_end = (STRING_LOC (string, end));
  704.       char * char_scan = (XTERM_CHAR_LOC (xw, index));
  705.       char * hl_scan = (XTERM_HL_LOC (xw, index));
  706.       while (string_scan < string_end)
  707.     {
  708.       (*char_scan++) = (*string_scan++);
  709.       (*hl_scan++) = hl;
  710.     }
  711.     }
  712.     XTERM_DRAW_CHARS
  713.       (xw, x, y, (XTERM_CHAR_LOC (xw, index)), length, (XTERM_HL_GC (xw, hl)));
  714.     if ((x <= (XW_CURSOR_X (xw))) && ((XW_CURSOR_X (xw)) < (x + length))
  715.     && (y == (XW_CURSOR_Y (xw))))
  716.       {
  717.     (XW_CURSOR_VISIBLE_P (xw)) = 0;
  718.     xterm_draw_cursor (xw);
  719.       }
  720.   }
  721.   PRIMITIVE_RETURN (UNSPECIFIC);
  722. }
  723.  
  724. static void
  725. DEFUN (xterm_clear_rectangle, (xw, x_start, x_end, y_start, y_end, hl),
  726.        struct xwindow * xw AND
  727.        unsigned int x_start AND
  728.        unsigned int x_end AND
  729.        unsigned int y_start AND
  730.        unsigned int y_end AND
  731.        unsigned int hl)
  732. {
  733.   unsigned int x_length = (x_end - x_start);
  734.   unsigned int y;
  735.   for (y = y_start; (y < y_end); y += 1)
  736.     {
  737.       unsigned int index = (XTERM_CHAR_INDEX (xw, x_start, y));
  738.       {
  739.     char * scan = (XTERM_CHAR_LOC (xw, index));
  740.     char * end = (scan + x_length);
  741.     while (scan < end)
  742.       (*scan++) = BLANK_CHAR;
  743.       }
  744.       {
  745.     char * scan = (XTERM_HL_LOC (xw, index));
  746.     char * end = (scan + x_length);
  747.     while (scan < end)
  748.       (*scan++) = hl;
  749.       }
  750.     }
  751.   if (hl == 0)
  752.     XClearArea ((XW_DISPLAY (xw)),
  753.         (XW_WINDOW (xw)),
  754.         (XTERM_X_PIXEL (xw, x_start)),
  755.         (XTERM_Y_PIXEL (xw, y_start)),
  756.         (x_length * (FONT_WIDTH (XW_FONT (xw)))),
  757.         ((y_end - y_start) * (FONT_HEIGHT (XW_FONT (xw)))),
  758.         False);
  759.   else
  760.     {
  761.       GC hl_gc = (XTERM_HL_GC (xw, hl));
  762.       for (y = y_start; (y < y_end); y += 1)
  763.     XTERM_DRAW_CHARS
  764.       (xw, x_start, y,
  765.        (XTERM_CHAR_LOC (xw, (XTERM_CHAR_INDEX (xw, x_start, y)))),
  766.        x_length, hl_gc);
  767.     }
  768. }
  769.  
  770. DEFINE_PRIMITIVE ("XTERM-CLEAR-RECTANGLE!", Prim_xterm_clear_rectangle, 6, 6, 0)
  771. {
  772.   PRIMITIVE_HEADER (6);
  773.   {
  774.     struct xwindow * xw = (x_window_arg (1));
  775.     unsigned int x_end = (arg_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
  776.     unsigned int y_end = (arg_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
  777.     unsigned int x_start = (arg_index_integer (2, (x_end + 1)));
  778.     unsigned int y_start = (arg_index_integer (4, (y_end + 1)));
  779.     unsigned int hl = (HL_ARG (6));
  780.     if ((x_start < x_end) && (y_start < y_end))
  781.       {
  782.     xterm_clear_rectangle (xw, x_start, x_end, y_start, y_end, hl);
  783.     if (CURSOR_IN_RECTANGLE (xw, x_start, x_end, y_start, y_end))
  784.       {
  785.         (XW_CURSOR_VISIBLE_P (xw)) = 0;
  786.         xterm_draw_cursor (xw);
  787.       }
  788.       }
  789.   }
  790.   PRIMITIVE_RETURN (UNSPECIFIC);
  791. }
  792.  
  793. static void
  794. DEFUN (xterm_scroll_lines_up, (xw, x_start, x_end, y_start, y_end, lines),
  795.        struct xwindow * xw AND
  796.        unsigned int x_start AND
  797.        unsigned int x_end AND
  798.        unsigned int y_start AND
  799.        unsigned int y_end AND
  800.        unsigned int lines)
  801. {
  802.   {
  803.     unsigned int y_to = y_start;
  804.     unsigned int y_from = (y_to + lines);
  805.     while (y_from < y_end)
  806.       xterm_copy_map_line (xw, x_start, x_end, (y_from++), (y_to++));
  807.   }
  808.   XCopyArea ((XW_DISPLAY (xw)),
  809.          (XW_WINDOW (xw)),
  810.          (XW_WINDOW (xw)),
  811.          (XW_NORMAL_GC (xw)),
  812.          (XTERM_X_PIXEL (xw, x_start)),
  813.          (XTERM_Y_PIXEL (xw, (y_start + lines))),
  814.          ((x_end - x_start) * (FONT_WIDTH (XW_FONT (xw)))),
  815.          (((y_end - y_start) - lines) * (FONT_HEIGHT (XW_FONT (xw)))),
  816.          (XTERM_X_PIXEL (xw, x_start)),
  817.          (XTERM_Y_PIXEL (xw, y_start)));
  818. }
  819.  
  820. DEFINE_PRIMITIVE ("XTERM-SCROLL-LINES-UP", Prim_xterm_scroll_lines_up, 6, 6,
  821.   "(XTERM-SCROLL-LINES-UP XTERM X-START X-END Y-START Y-END LINES)\n\
  822. Scroll the contents of the region up by LINES.")
  823. {
  824.   PRIMITIVE_HEADER (6);
  825.   {
  826.     struct xwindow * xw = (x_window_arg (1));
  827.     unsigned int x_end = (arg_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
  828.     unsigned int x_start = (arg_index_integer (2, (x_end + 1)));
  829.     unsigned int y_end = (arg_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
  830.     unsigned int y_start = (arg_index_integer (4, (y_end + 1)));
  831.     unsigned int lines = (arg_index_integer (6, (y_end - y_start)));
  832.     if ((0 < lines) && (x_start < x_end) && (y_start < y_end))
  833.       {
  834.     if (CURSOR_IN_RECTANGLE (xw, x_start, x_end, (y_start + lines), y_end))
  835.       {
  836.         xterm_erase_cursor (xw);
  837.         xterm_scroll_lines_up (xw, x_start, x_end, y_start, y_end, lines);
  838.         xterm_draw_cursor (xw);
  839.       }
  840.     else
  841.       {
  842.         xterm_scroll_lines_up (xw, x_start, x_end, y_start, y_end, lines);
  843.         if (CURSOR_IN_RECTANGLE
  844.         (xw, x_start, x_end, y_start, (y_end - lines)))
  845.           {
  846.         (XW_CURSOR_VISIBLE_P (xw)) = 0;
  847.         xterm_draw_cursor (xw);
  848.           }
  849.       }
  850.       }
  851.   }
  852.   PRIMITIVE_RETURN (UNSPECIFIC);
  853. }
  854.  
  855. static void
  856. DEFUN (xterm_scroll_lines_down, (xw, x_start, x_end, y_start, y_end, lines),
  857.        struct xwindow * xw AND
  858.        unsigned int x_start AND
  859.        unsigned int x_end AND
  860.        unsigned int y_start AND
  861.        unsigned int y_end AND
  862.        unsigned int lines)
  863. {
  864.   {
  865.     unsigned int y_to = y_end;
  866.     unsigned int y_from = (y_to - lines);
  867.     while (y_from > y_start)
  868.       xterm_copy_map_line (xw, x_start, x_end, (--y_from), (--y_to));
  869.   }
  870.   XCopyArea ((XW_DISPLAY (xw)),
  871.          (XW_WINDOW (xw)),
  872.          (XW_WINDOW (xw)),
  873.          (XW_NORMAL_GC (xw)),
  874.          (XTERM_X_PIXEL (xw, x_start)),
  875.          (XTERM_Y_PIXEL (xw, y_start)),
  876.          ((x_end - x_start) * (FONT_WIDTH (XW_FONT (xw)))),
  877.          (((y_end - y_start) - lines) * (FONT_HEIGHT (XW_FONT (xw)))),
  878.          (XTERM_X_PIXEL (xw, x_start)),
  879.          (XTERM_Y_PIXEL (xw, (y_start + lines))));
  880. }
  881.  
  882. DEFINE_PRIMITIVE ("XTERM-SCROLL-LINES-DOWN", Prim_xterm_scroll_lines_down, 6, 6,
  883.   "(XTERM-SCROLL-LINES-DOWN XTERM X-START X-END Y-START Y-END LINES)\n\
  884. Scroll the contents of the region down by LINES.")
  885. {
  886.   PRIMITIVE_HEADER (6);
  887.   {
  888.     struct xwindow * xw = (x_window_arg (1));
  889.     unsigned int x_end = (arg_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
  890.     unsigned int x_start = (arg_index_integer (2, (x_end + 1)));
  891.     unsigned int y_end = (arg_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
  892.     unsigned int y_start = (arg_index_integer (4, (y_end + 1)));
  893.     unsigned int lines = (arg_index_integer (6, (y_end - y_start)));
  894.     if ((0 < lines) && (x_start < x_end) && (y_start < y_end))
  895.       {
  896.     if (CURSOR_IN_RECTANGLE (xw, x_start, x_end, y_start, (y_end - lines)))
  897.       {
  898.         xterm_erase_cursor (xw);
  899.         xterm_scroll_lines_down
  900.           (xw, x_start, x_end, y_start, y_end, lines);
  901.         xterm_draw_cursor (xw);
  902.       }
  903.     else
  904.       {
  905.         xterm_scroll_lines_down
  906.           (xw, x_start, x_end, y_start, y_end, lines);
  907.         if (CURSOR_IN_RECTANGLE
  908.         (xw, x_start, x_end, (y_start + lines), y_end))
  909.           {
  910.         (XW_CURSOR_VISIBLE_P (xw)) = 0;
  911.         xterm_draw_cursor (xw);
  912.           }
  913.       }
  914.       }
  915.   }
  916.   PRIMITIVE_RETURN (UNSPECIFIC);
  917. }
  918.  
  919. DEFINE_PRIMITIVE ("XTERM-SAVE-CONTENTS", Prim_xterm_save_contents, 5, 5,
  920.   "(XTERM-SAVE-CONTENTS XW X-START X-END Y-START Y-END)\n\
  921. Get the contents of the terminal screen rectangle as a string.\n\
  922. The string contains alternating (CHARACTER, HIGHLIGHT) pairs.\n\
  923. The pairs are organized in row-major order from (X-START, Y-START).")
  924. {
  925.   PRIMITIVE_HEADER (5);
  926.   {
  927.     struct xwindow * xw = (x_window_arg (1));
  928.     unsigned int x_end = (arg_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
  929.     unsigned int y_end = (arg_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
  930.     unsigned int x_start = (arg_index_integer (2, (x_end + 1)));
  931.     unsigned int y_start = (arg_index_integer (4, (y_end + 1)));
  932.     unsigned int x_length = (x_end - x_start);
  933.     unsigned int string_length = (2 * x_length * (y_end - y_start));
  934.     SCHEME_OBJECT string = (allocate_string (string_length));
  935.     if (string_length > 0)
  936.       {
  937.     char * string_scan = ((char *) (STRING_LOC (string, 0)));
  938.     unsigned int y;
  939.     for (y = y_start; (y < y_end); y += 1)
  940.       {
  941.         unsigned int index = (XTERM_CHAR_INDEX (xw, x_start, y));
  942.         char * char_scan = (XTERM_CHAR_LOC (xw, index));
  943.         char * char_end = (char_scan + x_length);
  944.         char * hl_scan = (XTERM_HL_LOC (xw, index));
  945.         while (char_scan < char_end)
  946.           {
  947.         (*string_scan++) = (*char_scan++);
  948.         (*string_scan++) = (*hl_scan++);
  949.           }
  950.       }
  951.       }
  952.     PRIMITIVE_RETURN (string);
  953.   }
  954. }
  955.  
  956. DEFINE_PRIMITIVE ("XTERM-RESTORE-CONTENTS", Prim_xterm_restore_contents, 6, 6,
  957.   "(xterm-restore-contents xterm x-start x-end y-start y-end contents)\n\
  958. Replace the terminal screen rectangle with CONTENTS.\n\
  959. See `XTERM-SCREEN-CONTENTS' for the format of CONTENTS.")
  960. {
  961.   PRIMITIVE_HEADER (6);
  962.   CHECK_ARG (6, STRING_P);
  963.   {
  964.     struct xwindow * xw = (x_window_arg (1));
  965.     unsigned int x_end = (arg_index_integer (3, ((XW_X_CSIZE (xw)) + 1)));
  966.     unsigned int y_end = (arg_index_integer (5, ((XW_Y_CSIZE (xw)) + 1)));
  967.     unsigned int x_start = (arg_index_integer (2, (x_end + 1)));
  968.     unsigned int y_start = (arg_index_integer (4, (y_end + 1)));
  969.     unsigned int x_length = (x_end - x_start);
  970.     unsigned int string_length = (2 * x_length * (y_end - y_start));
  971.     SCHEME_OBJECT string = (ARG_REF (6));
  972.     if ((STRING_LENGTH (string)) != string_length)
  973.       error_bad_range_arg (6);
  974.     if (string_length > 0)
  975.       {
  976.     char * string_scan = ((char *) (STRING_LOC (string, 0)));
  977.     unsigned int y;
  978.     for (y = y_start; (y < y_end); y += 1)
  979.       {
  980.         unsigned int index = (XTERM_CHAR_INDEX (xw, x_start, y));
  981.         char * char_scan = (XTERM_CHAR_LOC (xw, index));
  982.         char * char_end = (char_scan + x_length);
  983.         char * hl_scan = (XTERM_HL_LOC (xw, index));
  984.         while (char_scan < char_end)
  985.           {
  986.         (*char_scan++) = (*string_scan++);
  987.         (*hl_scan++) = (*string_scan++);
  988.           }
  989.       }
  990.     xterm_dump_contents (xw, x_start, x_end, y_start, y_end);
  991.       }
  992.   }
  993.   PRIMITIVE_RETURN (UNSPECIFIC);
  994. }
  995.